package com.xmtlxx.web.controller.center;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import com.xmtlxx.common.annotation.Log;
import com.xmtlxx.common.annotation.RepeatSubmit;
import com.xmtlxx.common.core.controller.BaseController;
import com.xmtlxx.common.core.domain.PageQuery;
import com.xmtlxx.common.core.domain.R;
import com.xmtlxx.common.core.domain.entity.SysUser;
import com.xmtlxx.common.core.page.TableDataInfo;
import com.xmtlxx.common.core.validate.AddGroup;
import com.xmtlxx.common.core.validate.QueryGroup;
import com.xmtlxx.common.enums.BusinessType;
import com.xmtlxx.common.exception.ServiceException;
import com.xmtlxx.common.helper.LoginHelper;
import com.xmtlxx.common.utils.DateUtils;
import com.xmtlxx.common.utils.StringUtils;
import com.xmtlxx.common.utils.file.BASE64DecodedMultipartFile;
import com.xmtlxx.oms.domain.bo.CancelTaskBo;
import com.xmtlxx.oms.domain.bo.TaskBo;
import com.xmtlxx.oms.domain.vo.*;
import com.xmtlxx.system.domain.SysOss;
import com.xmtlxx.system.service.ISysConfigService;
import com.xmtlxx.system.service.ISysOssService;
import com.xmtlxx.system.service.ISysUserService;
import com.xmtlxx.tms.domain.bo.OrderBo;
import com.xmtlxx.tms.domain.bo.WaybillDtlBo;
import com.xmtlxx.tms.domain.vo.*;
import com.xmtlxx.web.controller.center.service.ICommonService;
import com.xmtlxx.web.controller.center.service.IMobileService;
import com.xmtlxx.web.controller.center.vo.BatchHandover;
import com.xmtlxx.web.controller.oms.service.IStagingService;
import com.xmtlxx.web.controller.oms.service.ITaskService;
import com.xmtlxx.web.controller.tms.service.IOrderService;
import com.xmtlxx.web.controller.tms.service.IWaybillDtlService;
import com.xmtlxx.web.controller.tms.service.IWaybillService;
import com.xmtlxx.web.controller.wms.service.*;
import com.xmtlxx.wms.domain.bo.*;
import com.xmtlxx.wms.domain.vo.*;
import com.xmtlxx.wms.service.IInventoryService;
import io.swagger.annotations.*;
import lombok.RequiredArgsConstructor;
import net.coobird.thumbnailator.Thumbnails;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.springframework.http.MediaType;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import javax.imageio.ImageIO;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.List;
import java.util.*;

@Validated
@Api(value = "手机控制中心", tags = {"业务调度控制中心"})
@RequiredArgsConstructor
@RestController
@RequestMapping("/app")
public class MobileController extends BaseController {

    private final ISysOssService iSysOssService;

    private final IHandoverService iHandoverService;

    private final IOrderService iOrderService;

    private final IWaybillService iWaybillService;

    private final IWaybillDtlService iWaybillDtlService;

    private final IWarehouseService iWarehouseService;

    private final IExWarehouseService iExWarehouseService;

    private final ITaskService iTaskService;

    private final ISysUserService iSysUserService;

    private final SmartCabinetService smartCabinetService;

    private final IPutTaskService iPutTaskService;

    private final IPutDtlService iPutDtlService;

    private final IInventoryService iInventoryService;

    private final IInventoryPlanService inventoryPlanService;

    private final IMobileService mobileService;

    private final ISysConfigService configService;

    private final ICommonService commonService;

    private final IStagingService stagingService;

    /**
     * 签名上传
     * 签名旋转
     */
    @ApiOperation("上传OSS对象存储")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataTypeClass = File.class, required = true)
    })
//    @SaCheckPermission("system:oss:upload")
    @Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
    @PostMapping("/upload")
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, String>> appUpload(@RequestPart("file") MultipartFile file, String lng, String lat, String addr) throws IOException {

        if (ObjectUtil.isNull(file)) {
            throw new ServiceException("上传文件不能为空");
        }
        Map<String, Object> params = new HashMap<>();
//        lng = "118.998989";
//        lat = "24.99876878";
//        addr = "福建省厦门市集美区杏林街道宁宝花园文达路21号4梯507室";
        if (StringUtils.isNotBlank(lng) && StringUtils.isNotBlank(lat) && StringUtils.isNotBlank(addr)) {
//            String text = "陈荣瑜_01:54_2022.06.06_福建省厦门市集美区杏林街道宁宝花园文达路21号4梯507室_118.998989 24.99876878";
            String text = LoginHelper.getNickname() + "_"
                    + DateUtils.date2String(new Date(), "HH:mm") + "_"
                    + DateUtils.date2String(new Date(), "yyyy-MM-dd") + "_"
                    + addr + "_"
                    + lng + " " + lat;
            params.put("mark", 1);
            params.put("text", text);
        }

        //上传
//        SysOss oss = iSysOssService.upload(file,params);

        File newImage = MultipartFileToFile(file);
        String suffix = newImage.getPath().substring(newImage.getPath().lastIndexOf(".") + 1);
        Thumbnails.Builder<File> thumbnails = Thumbnails.of(newImage).scale(1).rotate(-90);
        thumbnails.outputFormat(suffix).allowOverwrite(true).toFile(newImage);

        MultipartFile routerFile = fileToMultipartFile(newImage);
        SysOss tOss = iSysOssService.upload(routerFile, params);

        // 设定背景色
        BufferedImage image = ImageIO.read(newImage);
        BufferedImage result = new BufferedImage(
                image.getWidth(),
                image.getHeight(),
                BufferedImage.TYPE_INT_RGB);

        Graphics2D graphic = result.createGraphics();
        graphic.drawImage(image, 0, 0, Color.WHITE, null);
        graphic.dispose();
        ImageIO.write(result, "png", new File(newImage.getPath()));

        MultipartFile multipartFile = fileToMultipartFile(newImage);
        SysOss oss = iSysOssService.upload(multipartFile, params);


//        SysOssConfigVo config = iSysOssConfigService.getDefaultConfig();
//
//        // 上传文件路径
//        String filePath = config.getBucketName()+"/"+oss.getFileName();
//
//        File img = new File(filePath);
//        String suffix = oss.getFileName().substring(oss.getFileName().lastIndexOf(".") + 1);
//
//        // 设定背景色
//        BufferedImage image = ImageIO.read(img);
//        BufferedImage result = new BufferedImage(
//            image.getWidth(),
//            image.getHeight(),
//            BufferedImage.TYPE_INT_RGB);
//
//        Graphics2D graphic = result.createGraphics();
//        graphic.drawImage(image, 0, 0, Color.WHITE, null);
//        graphic.dispose();
//        ImageIO.write(result,  "png",  new File(filePath));
//        //图片旋转
//        File newImage = new File(filePath);
//        Thumbnails.Builder<File> thumbnails = Thumbnails.of(newImage).scale(1).rotate(-90);
//        thumbnails.outputFormat(suffix).allowOverwrite(true).toFile(newImage);

        Map<String, String> map = new HashMap<>(2);
        map.put("url", oss.getUrl());
        map.put("fileName", oss.getFileName());
        map.put("ossId", oss.getOssId().toString());
        map.put("tOssId", tOss.getOssId().toString());
        return R.ok(map);
    }

    /**
     * 将MultipartFile转换为File
     *
     * @param multiFile
     * @return
     */
    public static File MultipartFileToFile(MultipartFile multiFile) {
        // 获取文件名
        String fileName = multiFile.getOriginalFilename();
        // 获取文件后缀
        String prefix = fileName.substring(0, fileName.indexOf("."));
        String suffix = fileName.substring(fileName.lastIndexOf("."));
        // 若须要防止生成的临时文件重复,能够在文件名后添加随机码

        try {
            File file = File.createTempFile(prefix, suffix);
            multiFile.transferTo(file);
            return file;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static MultipartFile fileToMultipartFile(File file) {

        FileItem fileItem = createFileItem(file);
        MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
        return multipartFile;
    }

    private static FileItem createFileItem(File file) {

        FileItem item = new DiskFileItemFactory().createItem("file", MediaType.MULTIPART_FORM_DATA_VALUE, true, file.getName());
        int bytesRead = 0;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    public String getPath(String prefix, String suffix) {
        // 生成uuid
        String uuid = IdUtil.fastSimpleUUID();
        // 文件路径
        String path = DateUtils.datePath() + "/" + uuid;
        if (StringUtils.isNotBlank(prefix)) {
            path = prefix + "/" + path;
        }
        return path + suffix;
    }

    /**
     * 上传OSS对象存储
     */
    @ApiOperation("上传OSS对象存储")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "文件", paramType = "query", dataTypeClass = File.class, required = true)
    })
//    @SaCheckPermission("system:oss:upload")
    @Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
    @PostMapping("/fileUpload")
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, String>> fileUpload(@RequestPart("file") MultipartFile file, String lng, String lat, String addr) {

        if (ObjectUtil.isNull(file)) {
            throw new ServiceException("上传文件不能为空");
        }
        Map<String, Object> params = new HashMap<>();
//        lng = "118.998989";
//        lat = "24.99876878";
//        addr = "福建省厦门市集美区杏林街道宁宝花园文达路21号4梯507室";
        if (StringUtils.isNotBlank(lng) && StringUtils.isNotBlank(lat) && StringUtils.isNotBlank(addr)) {
//            String text = "陈荣瑜_01:54_2022.06.06_福建省厦门市集美区杏林街道宁宝花园文达路21号4梯507室_118.998989 24.99876878";
            String text = LoginHelper.getNickname() + "_"
                    + DateUtils.date2String(new Date(), "HH:mm") + "_"
                    + DateUtils.date2String(new Date(), "yyyy-MM-dd") + "_"
                    + addr + "_"
                    + lng + " " + lat;
            params.put("mark", 1);
            params.put("text", text);
        }

        SysOss oss = iSysOssService.upload(file, params);
        Map<String, String> map = new HashMap<>(2);
        map.put("url", oss.getUrl());
        map.put("fileName", oss.getFileName());
        map.put("ossId", oss.getOssId().toString());
        map.put("originalName", oss.getOriginalName());
        return R.ok(map);
    }

    @PostMapping("/handvoerBean/{id}/{action}")
    public R<HandoverVo> handvoerBean(@ApiParam("主键串")
                                      @NotEmpty(message = "主键不能为空")
                                      @PathVariable String id, @PathVariable String action) {

        return R.ok(mobileService.handoverBeanVo(id, action));
    }

    @PostMapping("/getHandvoerInfo/{id}/{action}")
    public R<HandoverVo> getHandvoerInfo(@ApiParam("主键串")
                                         @NotEmpty(message = "主键不能为空")
                                         @PathVariable String id, @PathVariable String action) {

        HandoverVo vo = null;
        HandoverBo bo = new HandoverBo();
        OrderVo wayOrder = null;
        WaybillVo waybillVo = null;
        if (StringUtils.isNotEmpty(action)) {
            switch (action) {
                case "0"://从订单进行取件交接
                    OrderVo orderVo = iOrderService.queryById(id);
                    bo.setObjid(orderVo.getTaskId());
                    bo.setType("0");
                    vo = iHandoverService.queryByObjid(bo);

                    break;
                case "1"://从运单进行收件交接
                    waybillVo = iWaybillService.queryById(id);
                    wayOrder = iOrderService.queryById(waybillVo.getOrderId());
                    bo.setObjid(wayOrder.getTaskId());
                    bo.setType("1");
                    vo = iHandoverService.queryByObjid(bo);
                    break;
                case "2"://从运单暂存
//                    waybillVo = iWaybillService.queryById(id);
//                    wayOrder = iOrderService.queryById(waybillVo.getOrderId());
//                    bo.setObjid(wayOrder.getTaskId());
//                    bo.setType("1");
//                    vo = iHandoverService.queryByObjid(bo);
                    ExWarehouseVo exWarehouseVo = iExWarehouseService.queryById(id);
                    bo.setObjid(exWarehouseVo.getTaskId());
                    bo.setType("1");
                    vo = iHandoverService.queryByObjid(bo);
                    break;
                case "3"://从入库单进行收件交接
                    WarehouseVo warehouseVo = iWarehouseService.queryById(id);
                    bo.setObjid(warehouseVo.getTaskId());
                    bo.setType("1");
                    vo = iHandoverService.queryByObjid(bo);
                    break;
                default:
                    break;
            }
        }

        return R.ok(vo);
    }

    /**
     * 新增交接信息
     */
    @ApiOperation("新增交接信息")
    @Log(title = "交接信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/handover")
    public R<Void> handover(@Validated(AddGroup.class) @RequestBody HandoverVo vo) {

        boolean flag = false;
        HandoverBo bo = new HandoverBo();
        BeanUtil.copyProperties(vo, bo);
        //新增交接信息

        List<HandoverDtlVo> dtls = vo.getItems();

        //OMS明细回填
        //取件操作
        TaskVo taskVo = iTaskService.queryById(vo.getObjid());
        if (taskVo == null) {
            taskVo = iTaskService.queryById(iOrderService.queryById(iWaybillService.queryById(vo.getObjid()).getOrderId()).getTaskId());
        }
        TaskBo taskBo = new TaskBo();
        BeanUtil.copyProperties(taskVo, taskBo);
        List<TaskDtlVo> tdtls = new ArrayList<>();
        for (HandoverDtlVo item : dtls) {
            TaskDtlVo tdtl = new TaskDtlVo();
            BeanUtil.copyProperties(item, tdtl, "id");
            tdtl.setDelFlag("0");
            tdtls.add(tdtl);
        }
        taskBo.setItems(tdtls);
        iTaskService.updateByBo(taskBo);

        bo.setObjid(taskVo.getId());
//        flag = iHandoverService.insertByBo(bo);

        if (flag) {
            //订单交接明细回填
            OrderVo orderVo = iOrderService.queryByTaskId(vo.getObjid());
            OrderBo orderBo = new OrderBo();
            if (orderVo != null) {
                orderVo.setStatus("1");//取件交接
                List<OrderDtlVo> odtls = new ArrayList<>();
                for (HandoverDtlVo item : dtls) {
                    OrderDtlVo odtl = new OrderDtlVo();
                    BeanUtil.copyProperties(item, odtl, "id");
                    odtls.add(odtl);
                }
                orderBo.setItems(odtls);
                BeanUtil.copyProperties(orderVo, orderBo);
                iOrderService.updateByBo(orderBo);
            }

            //WMS明细回填
            if (StringUtils.isNotEmpty(vo.getOrderType())) {
                switch (vo.getOrderType()) {
                    case "0"://入库
                        WarehouseVo warehouseVo = iWarehouseService.queryByTaskId(vo.getObjid());
                        WarehouseBo warehouseBo = new WarehouseBo();
                        if (warehouseVo == null) {
                            warehouseVo = iWarehouseService.queryById(vo.getObjid());
                        }
                        if (warehouseVo != null) {
                            if (warehouseVo.getFlag().equals("1")) {
                                warehouseVo.setIsSign("1");//自行配送：是否到货
                            }
                            BeanUtil.copyProperties(warehouseVo, warehouseBo);
                            List<WarehouseDtlVo> wdtls = new ArrayList<>();
                            for (HandoverDtlVo item : dtls) {
                                WarehouseDtlVo wdtl = new WarehouseDtlVo();
                                BeanUtil.copyProperties(item, wdtl, "id");
                                wdtls.add(wdtl);
                            }
                            warehouseBo.setItems(wdtls);
                            iWarehouseService.updateByBo(warehouseBo);
                        }

                        break;
                    case "1"://出库
                        ExWarehouseVo exWarehouseVo = iExWarehouseService.queryByTaskId(vo.getObjid());
                        ExWarehouseBo exWarehouseBo = new ExWarehouseBo();
                        if (exWarehouseVo == null) {
                            exWarehouseVo = iExWarehouseService.queryById(vo.getObjid());
                        }
                        if (exWarehouseVo != null) {
                            BeanUtil.copyProperties(exWarehouseVo, exWarehouseBo);
                            List<ExWarehouseDtlVo> edtls = new ArrayList<>();
                            for (HandoverDtlVo item : dtls) {
                                ExWarehouseDtlVo edtl = new ExWarehouseDtlVo();
                                BeanUtil.copyProperties(item, edtl, "id");
                                edtls.add(edtl);
                            }
                            exWarehouseBo.setItems(edtls);
                            iExWarehouseService.updateByBo(exWarehouseBo);
                        }
                        break;
                    case "3"://调用
                        ExWarehouseVo transferVo = iExWarehouseService.queryByTaskId(vo.getObjid());
                        ExWarehouseBo transferBo = new ExWarehouseBo();
                        if (transferVo == null) {
                            transferVo = iExWarehouseService.queryById(vo.getObjid());
                        }
                        if (transferVo != null) {
                            BeanUtil.copyProperties(transferVo, transferBo);
                            List<ExWarehouseDtlVo> trdtls = new ArrayList<>();
                            for (HandoverDtlVo item : dtls) {
                                ExWarehouseDtlVo trdtl = new ExWarehouseDtlVo();
                                BeanUtil.copyProperties(item, trdtl, "id");
                                trdtls.add(trdtl);
                            }
                            transferBo.setItems(trdtls);
                            iExWarehouseService.updateByBo(transferBo);
                        }
                        break;
                    default:
                        break;
                }
            }
        }
        return toAjax(flag);
    }

    /**
     * 新增交接信息
     */
    @ApiOperation("新增交接信息")
    @Log(title = "交接信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/handoverV2")
    public R<Void> handoverV2(@Validated(AddGroup.class) @RequestBody HandoverBo bo) {

        Boolean flag = mobileService.handoverSave(bo);
        if (flag) {//交接图片推送
            commonService.autographPush(bo.getId());
        }
        return toAjax(flag);
    }

    /**
     * 新增交接信息
     */
    @ApiOperation("批量签收")
    @Log(title = "批量签收", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @Transactional(rollbackFor = Exception.class)
    @PostMapping("/batchHandover")
    public R<Void> batchHandover(@Validated(AddGroup.class) @RequestBody BatchHandover bo) {

        return toAjax(mobileService.batchHandover(bo));
    }

    /**
     * 订单操作--初始化派遣任务
     */
    @ApiOperation("订单操作")
    @Log(title = "TMS订单操作", businessType = BusinessType.UPDATE)
    @PostMapping("/dispatchBean/{id}")
    @Transactional(rollbackFor = Exception.class)
    public R<OrderVo> dispatchBean(@ApiParam("主键串")
                                   @NotEmpty(message = "主键不能为空")
                                   @PathVariable String id) {

        OrderVo vo = iOrderService.queryById(id);
        vo.setPhone1(configService.selectConfigByKey("app.tms.phone.one"));
        vo.setPhone2(configService.selectConfigByKey("app.tms.phone.two"));
        return R.ok(vo);
    }

    /**
     * 订单操作
     */
    @ApiOperation("TMS订单派车")
    @Log(title = "TMS订单派车", businessType = BusinessType.UPDATE)
    @PostMapping("/dispatch")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> dispatch(@Validated(AddGroup.class) @RequestBody DispatchVo vo) {

        return toAjax(mobileService.dispatch(vo));
    }

    /**
     * 运单操作
     */
    @ApiOperation("运单操作")
    @Log(title = "运单操作", businessType = BusinessType.UPDATE)
    @PostMapping("/operation")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> operation(@Validated(AddGroup.class) @RequestBody WaybillVo vo) {

        return toAjax(mobileService.waybillOperation(vo));
    }

    /**
     * 运单操作
     */
    @ApiOperation("运单操作--车辆")
    @Log(title = "车辆运单操作", businessType = BusinessType.UPDATE)
    @PostMapping("/operationByCar")
    @Transactional(rollbackFor = Exception.class)
    public R<Void> operationByCar(@Validated(AddGroup.class) @RequestBody OrderVo vo) {

        return toAjax(mobileService.waybillOperationByCar(vo));
    }

    @ApiOperation("缓存交接附件信息")
    @Log(title = "上传交接附件", businessType = BusinessType.INSERT)
    @PostMapping("/uploadDtlBase64")
    @Transactional(rollbackFor = Exception.class)
    public R<Map<String, String>> uploadDtlBase64(@Validated(AddGroup.class) @RequestBody PhotoVo vo) {

        MultipartFile file = BASE64DecodedMultipartFile.base64ToMultipart(vo.getBase64Url());
        Map<String, Object> params = new HashMap<>();
        String text = LoginHelper.getNickname() + "_"
                + DateUtils.date2String(new Date(), "HH:mm:ss.SSS") + "_"
                + DateUtils.date2String(new Date(), "yyyy-MM-dd");
        params.put("mark", 1);
        params.put("text", text);
        SysOss oss = iSysOssService.upload(file, params);

        String ossId = oss.getOssId().toString();

        oss.setObjid(vo.getDtlId());
        oss.setBuss(vo.getUploadType());
        iSysOssService.updateOss(oss);

        Map<String, String> map = new HashMap<>(2);
        map.put("url", oss.getUrl());
        map.put("fileName", oss.getFileName());
        map.put("ossId", ossId);

        return R.ok(map);
    }

    /**
     * 获取承运商
     */
    @ApiOperation("获取承运商")
    @GetMapping("/getCarrierUser/{orderId}")
    public R<List<SysUser>> getCarrierUser(@PathVariable String orderId) {

        OrderVo vo = iOrderService.queryById(orderId);
        return R.ok(iSysUserService.selectUserByCar("smscys", vo.getCarrierDeptId()));
    }

    /**
     * 获取中转箱内的物品明细
     */
    @ApiOperation("获取中转箱内的物品明细")
    @GetMapping("/getWaybillByBox/{boxNo}")
    public R<List<WaybillDtlVo>> getWaybillByBox(@PathVariable String boxNo) {

        WaybillDtlBo bo = new WaybillDtlBo();
        bo.setBoxNo(boxNo);
        return R.ok(iWaybillDtlService.queryList(bo));
    }

    /**
     * 获取中转箱内的物品明细
     */
    @ApiOperation("获取保管箱内的物品明细")
    @GetMapping("/getPutTaskByBox/{boxNo}")
    public R<List<PutDtlVo>> getPutTaskByBox(@PathVariable String boxNo) {

        PutDtlBo bo = new PutDtlBo();
        bo.setBoxNo(boxNo);
        return R.ok(iPutDtlService.queryList(bo));
    }

    /**
     * 获取中转箱内的物品明细
     */
    @ApiOperation("获取保管箱内的物品明细")
    @GetMapping("/getInventoryByBox/{boxNo}")
    public R<List<InventoryVo>> getInventoryByBox(@PathVariable String boxNo) {

        InventoryBo bo = new InventoryBo();
        bo.setBoxNo(boxNo);
        List<InventoryVo> items = iInventoryService.queryList(bo);
        return R.ok(items);
    }

    @ApiOperation("签字板上传")
    @Log(title = "签字", businessType = BusinessType.INSERT)
    @PostMapping("/uploadPhotoBase64WidthTransfer")
    public R<Map<String, String>> uploadPhotoBase64WidthTransfer(@Validated(AddGroup.class) @RequestBody PhotoVo vo) throws IOException {

        MultipartFile file = BASE64DecodedMultipartFile.base64ToMultipart(vo.getBase64Url());
        File newImage = MultipartFileToFile(file);
        String suffix = newImage.getPath().substring(newImage.getPath().lastIndexOf(".") + 1);
        Thumbnails.Builder<File> thumbnails = Thumbnails.of(newImage).scale(1).rotate(-90);
        thumbnails.outputFormat(suffix).allowOverwrite(true).toFile(newImage);

        MultipartFile routerFile = fileToMultipartFile(newImage);
        SysOss tOss = iSysOssService.upload(routerFile, null);

        // 设定背景色
        BufferedImage image = ImageIO.read(newImage);
        BufferedImage result = new BufferedImage(
                image.getWidth(),
                image.getHeight(),
                BufferedImage.TYPE_INT_RGB);

        Graphics2D graphic = result.createGraphics();
        graphic.drawImage(image, 0, 0, Color.WHITE, null);
        graphic.dispose();
        ImageIO.write(result, "png", new File(newImage.getPath()));

        MultipartFile multipartFile = fileToMultipartFile(newImage);
        SysOss oss = iSysOssService.upload(multipartFile, null);


        Map<String, String> map = new HashMap<>(2);
        map.put("url", oss.getUrl());
        map.put("fileName", oss.getFileName());
        map.put("ossId", oss.getOssId().toString());
        map.put("tOssId", tOss.getOssId().toString());
        return R.ok(map);
    }

    @ApiOperation("用于返回一个初始化对象")
    @GetMapping("/initBeanByBoxNo/{boxNo}")
    R<InventoryPlanVo> initBeanByBoxNo(@PathVariable("boxNo") String boxNo) {

        return R.ok(inventoryPlanService.initBeanByBoxNo(boxNo));
    }

    @ApiOperation("签收操作")
    @Log(title = "物品签收操作", businessType = BusinessType.UPDATE)
    @PostMapping("/signPno")
    @Transactional(rollbackFor = Exception.class)
    public R<String> signPno(@Validated(AddGroup.class) @RequestBody PrintTaskDtlVo vo) {

        String uuid = vo.getUuid();
        if (vo.getItems() != null && vo.getItems().size() > 0) {
            for (PrintTaskDtlVo dtlVo : vo.getItems()) {
                //根据WayBill_Dtl_id 、Task_id 获取OMS Task、WareHouse
                WarehouseVo warehouseVo = iWarehouseService.queryByTaskId(dtlVo.getTaskId());
                //通过WareHouse初始化上架任务；
                if (warehouseVo != null) {
                    PutTaskVo putTask = iPutTaskService.queryPutTaskVoByWarehouseID(warehouseVo.getId());
                    if (putTask.getItems() != null && putTask.getItems().size() > 0) {
                        if (vo.getCtrl() == 0) {//签收
                            for (PutDtlVo item : putTask.getItems()) {
                                if (item.getPno().equals(dtlVo.getPno())) {
                                    if (StringUtils.isEmpty(uuid)) {//未创建任务
                                        uuid = UUID.randomUUID().toString();
                                    }
                                    AsynInfo.createAsynInfoByUUID(uuid, item, "签收队列:" + DateUtils.date2String(new Date()));
                                }
                            }
                        } else {//移除
                            if (StringUtils.isNotEmpty(uuid)) {
                                for (PutDtlVo item : putTask.getItems()) {
                                    if (item.getPno().equals(dtlVo.getPno())) {
                                        AsynInfo.deleteAsynInfoItem(uuid, item);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return R.ok(uuid);
    }

    @ApiOperation("查询打印任务列表")
    @GetMapping("/printProgresses")
    public R<List<AsynInfo>> printProgresses() {

        List<AsynInfo> items = new ArrayList<>();
        for (Map.Entry<String, AsynInfo> map : AsynInfo.allAsynInfo.entrySet()) {
            AsynInfo item = map.getValue();
            items.add(item);
        }
        return R.ok(items);
    }

    @ApiOperation("用于返回一个初始化对象")
    @GetMapping("/finishPrint/{uuid}")
    R<Void> finishPrint(@PathVariable("uuid") String uuid) {

        AsynInfo.deleteAsynInfo(uuid);
        return R.ok();
    }

    @ApiOperation("根据扫码模式进行筛选")
    @GetMapping("/getNoByList/{no}/{type}")
    R<List<Map<String, Object>>> getNoByList(@PathVariable("no") String no, @PathVariable("type") String type) {

        return R.ok(mobileService.getNoByList(no, type));
    }

    @ApiOperation("用于返回一个初始化对象")
    @GetMapping("/getPropertyInfo/{pno}")
    R<PropertyVo> getPropertyInfo(@PathVariable("pno") String pno) {

        return R.ok(mobileService.getPropertyInfo(pno));
    }

    @GetMapping("/police/indexCount")
    public R<Map<String, Object>> policeIndexCount() {

        Map<String, Object> result = new HashMap<>();
        result.put("datas", iInventoryService.countPoliceTotals());
        return R.ok(result);
    }

    @GetMapping("/police/datas")
    public R<Map<String, Object>> policeDatas() {

        Map<String, Object> result = new HashMap<>();
        result.put("datas", iInventoryService.countPoliceDatas());
        return R.ok(result);
    }

    @GetMapping("/police/regionTotals")
    public R<Map<String, Object>> regionTotals() {

        Map<String, Object> result = new HashMap<>();
        result.put("datas", iInventoryService.countRegionTotals());
        return R.ok(result);
    }

    @GetMapping("/police/policeDeptTotals")
    public R<Map<String, Object>> policeDeptTotals() {

        Map<String, Object> result = new HashMap<>();
        result.put("datas", iInventoryService.countPoliceDeptTotals());
        return R.ok(result);
    }

    @ApiOperation("查询选择库存财物列表")
    @GetMapping("/selectInventoryProperty/list")
    public TableDataInfo<SelectInventoryPropertyBo> selectInventoryPropertyList(PageQuery pageQuery,
                                                                                SelectInventoryPropertyBo bo) {

        return iInventoryService.selectInventoryPropertyList(pageQuery, bo);
    }

    /**
     * 公共数据方法
     */
    /**
     * 查询库存列表
     */
    @ApiOperation("查询库存列表")
    @GetMapping("/inventory/list")
    public R<List<InventoryVo>> inventoryList(@Validated(QueryGroup.class) InventoryBo bo) {

        return R.ok(iInventoryService.queryList(bo));
    }

    /**
     * 查询库存列表
     */
    @ApiOperation("查询库存列表")
    @GetMapping("/inventoryList")
    public TableDataInfo<InventoryVo> list(@Validated(QueryGroup.class) InventoryBo bo, PageQuery pageQuery) {

        if (bo != null && !StringUtils.isEmpty(bo.getPno())) {
            bo.setPnoSearchKey(bo.getPno());
            bo.setPno(null);
        }
        return iInventoryService.queryPageAppList(bo, pageQuery);
    }


    /**
     * 查询非中心财物
     */
    @ApiOperation("非中心财物列表")
    @GetMapping("/notCenterProList")
    public TableDataInfo<StagingVo> notCanterProList(String pno, PageQuery pageQuery) {

        return stagingService.getNotCanterProList(pno, pageQuery);
    }

    @GetMapping("/getTaskDtls/{ids}")
    public R<List<PropertyVo>> getTaskDtls(@ApiParam("主键串")
                                           @NotEmpty(message = "主键不能为空")
                                           @PathVariable String[] ids) {

        return R.ok(mobileService.getTaskDtls(Arrays.asList(ids)));
    }

    @ApiOperation("撤销订单列表")
    @GetMapping("/cancelTaskList")
    public TableDataInfo<CancelTaskBo> cancelTask(@Validated(QueryGroup.class) CancelTaskBo bo, PageQuery pageQuery) {

        return iTaskService.cancelTaskList(bo, pageQuery);
    }

    @ApiOperation("生成智能柜验证码")
    @GetMapping("/generateSmartCabinetCode/{type}/{id}")
    public R<Void> generateSmartCabinetCode(@NotNull(message = "类型不能为空") @PathVariable("type") Integer type,
                                            @NotEmpty(message = "主键不能为空") @PathVariable("id") String id) {

        return smartCabinetService.generateSmartCabinetCode(type, id) ? R.ok() : R.fail();
    }

    @ApiOperation("批量生成智能柜验证码")
    @GetMapping("/batchGenerateSmartCabinetCode/{type}/{ids}")
    public R<Void> batchGenerateSmartCabinetCode(
            @NotNull(message = "类型不能为空") @PathVariable("type") Integer type,
            @NotNull(message = "id不能为空") @PathVariable String[] ids) {

        return smartCabinetService.batchGenerateSmartCabinetCode(type, Arrays.asList(ids)) ? R.ok() : R.fail();
    }

}
